package controllers

import (
    "gouniapp/configs"
	"bytes"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"image"
	_ "image/jpeg" // 支持jpeg格式
	_ "image/png"  // 支持png格式
	"io"
	"net/http"
	"net/url"
	"strings"
)

func GetAccesstoken() (string, error) {
	clientID := configs.Config.GetString("baidu.BaiduAPIKey")
	clientSecret := configs.Config.GetString("baidu.BaiduSecretKey")
	if clientID == "" || clientSecret == "" {
		return "", fmt.Errorf("百度API密钥或密钥ID为空")
	}
	myurl := fmt.Sprintf("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s", clientID, clientSecret)
	// 使用http.Client和http.NewRequest来更灵活地管理请求
	req, err := http.NewRequest("POST", myurl, nil)
	if err != nil {
		return "", fmt.Errorf("创建请求失败: %v", err)
	}
	req.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	res, err := client.Do(req)
	if err != nil {
		return "", fmt.Errorf("请求失败: %v", err)
	}
	defer res.Body.Close()
	// 检查HTTP响应状态码
	if res.StatusCode != http.StatusOK {
		return "", fmt.Errorf("请求返回错误状态码: %d", res.StatusCode)
	}
	// 读取并解析响应内容
	body, err := io.ReadAll(res.Body)
	if err != nil {
		return "", fmt.Errorf("读取响应体失败: %v", err)
	}
	var tokenResp struct {
		AccessToken string `json:"access_token"`
	}
	if err := json.Unmarshal(body, &tokenResp); err != nil {
		return "", fmt.Errorf("解析JSON响应失败: %v", err)
	}
	// 返回access_token
	return tokenResp.AccessToken, nil
}

func UploadSfz(c *gin.Context) {
	// 获取百度AI的访问令牌
	accessToken, err := GetAccesstoken()
	if err != nil {
		JsonResponse(c, http.StatusInternalServerError, fmt.Sprintf("token获取失败: %v", err), nil)
		return
	}
	// 从前端请求中获取上传的图片数据
	file, _, err := c.Request.FormFile("file")
	if err != nil {
		fmt.Println(err)
		JsonResponse(c, http.StatusInternalServerError, "上传图片为空", nil)
		return
	}
	defer file.Close()

	// 读取图片数据
	imgData, err := io.ReadAll(file)
	if err != nil {
		fmt.Println(err)
		JsonResponse(c, http.StatusInternalServerError, "图片无法读取", nil)
		return
	}

	// 对图像数据进行处理
	processedImgStr, err := ProcessImageForOCR(imgData)
	if err != nil {
		fmt.Println(err)
		JsonResponse(c, http.StatusInternalServerError, "图片处理失败", nil)
		return
	}

	// 构建请求参数
	params := url.Values{}
	params.Set("id_card_side", "front")
	params.Set("image", processedImgStr)
	requestURL := "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + accessToken

	req, err := http.NewRequest("POST", requestURL, strings.NewReader(params.Encode()))
	if err != nil {
		fmt.Println(err)
		JsonResponse(c, http.StatusInternalServerError, "图片识别失败", nil)
		return
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

	client := &http.Client{}
	res, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		JsonResponse(c, http.StatusInternalServerError, "图片识别请求失败", nil)
		return
	}
	defer res.Body.Close()

	body, err := io.ReadAll(res.Body)
	if err != nil {
		fmt.Println(err)
		JsonResponse(c, http.StatusInternalServerError, "Failed to read response body", nil)
		return
	}

	fmt.Println(string(body))

	var responseData map[string]interface{}
	err = json.Unmarshal(body, &responseData)
	if err != nil {
		fmt.Println(err)
		JsonResponse(c, http.StatusInternalServerError, "Failed to parse response body", nil)
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code":    0,
		"message": "识别成功",
		"result":  responseData,
	})
}

func ProcessImageForOCR(imgData []byte) (string, error) {
	// 尝试解码图像数据
	_, format, err := image.Decode(bytes.NewReader(imgData))
	if err != nil {
		return "", err
	}

	// 检查图像格式是否支持
	if format != "jpeg" && format != "jpg" && format != "png" && format != "bmp" {
		return "", errors.New("Unsupported image format")
	}
	imgConfig, _, err := image.DecodeConfig(bytes.NewReader(imgData))
	if err != nil {
		return "", err
	}
	// 计算图像的最短边和最长边
	var minDimension int
	var maxDimension int
	if imgConfig.Width <= imgConfig.Height {
		minDimension = imgConfig.Width
		maxDimension = imgConfig.Height
	} else {
		minDimension = imgConfig.Height
		maxDimension = imgConfig.Width
	}

	// 检查图像尺寸是否符合要求
	if minDimension < 15 || maxDimension > 4096 {
		return "", errors.New("Image dimensions do not meet the requirements")
	}

	// 检查图像大小是否符合要求
	if len(imgData) > 4*1024*1024 {
		return "", errors.New("Image size exceeds 4MB")
	}

	// 将图像数据进行 Base64 编码
	imgStr := base64.StdEncoding.EncodeToString(imgData)

	return imgStr, nil
}
